using System.Collections.Generic;
using System.Data;
using UnityEditor;
using UnityEngine;


[CustomEditor(typeof(ItemDataManager))]
public class ItemDataManagerInspector : Editor
{
    ItemDataManager _target;
    public ItemDataManager Target { get { return _target ?? (_target = (ItemDataManager)target); } }
    List<ItemData> _dataList { get { return ReflectionTools.GetNonPublicField<List<ItemData>>(Target, "_dataList"); } }
    static HashSet<int> _isFoldList = new HashSet<int>();


    /// <summary> 更新是否展开某个数据 </summary>
    void UpdateFoldout(int index, bool isFold)
    {
        if (isFold) { _isFoldList.Add(index); }
        else { _isFoldList.Remove(index); }
    }


    /// <summary> 数据对象的UI </summary>
    static void OnDataUI(ItemData data)
    {
        ReflectionTools.SetNonPublicField(data, "_ItemID", EditorGUILayout.IntField("道具ID", ReflectionTools.GetNonPublicField<int>(data, "_ItemID")));
        ReflectionTools.SetNonPublicField(data, "_Name", EditorGUILayout.TextField("道具名称ID", ReflectionTools.GetNonPublicField<string>(data, "_Name")));
        ReflectionTools.SetNonPublicField(data, "_Icon", EditorGUILayout.TextField("道具Icon_ID", ReflectionTools.GetNonPublicField<string>(data, "_Icon")));
        ReflectionTools.SetNonPublicField(data, "_Quality", EditorGUILayout.IntField("道具品质", ReflectionTools.GetNonPublicField<int>(data, "_Quality")));
        ReflectionTools.SetNonPublicField(data, "_Type", EditorGUILayout.EnumPopup("道具类型", ReflectionTools.GetNonPublicField<ItemType>(data, "_Type")));
        ReflectionTools.SetNonPublicField(data, "_SType", EditorGUILayout.IntField("是否可以出售", ReflectionTools.GetNonPublicField<int>(data, "_SType")));
        ReflectionTools.SetNonPublicField(data, "_SPrice", EditorGUILayout.IntField("售出价格", ReflectionTools.GetNonPublicField<int>(data, "_SPrice")));
        ReflectionTools.SetNonPublicField(data, "_UType", EditorGUILayout.IntField("是否可以使用", ReflectionTools.GetNonPublicField<int>(data, "_UType")));
        ReflectionTools.SetNonPublicField(data, "_DropShow", EditorGUILayout.TextField("掉落显示", ReflectionTools.GetNonPublicField<string>(data, "_DropShow")));
        ReflectionTools.SetNonPublicField(data, "_AddValue", EditorGUILayout.IntField("增加货币", ReflectionTools.GetNonPublicField<int>(data, "_AddValue")));
        ReflectionTools.SetNonPublicField(data, "_DropType", EditorGUILayout.IntField("掉落类型", ReflectionTools.GetNonPublicField<int>(data, "_DropType")));
        ReflectionTools.SetNonPublicField(data, "_DropId", EditorGUILayout.IntField("调用掉落库", ReflectionTools.GetNonPublicField<int>(data, "_DropId")));
        ReflectionTools.SetNonPublicField(data, "_IsPiece", EditorGUILayout.Toggle("是否碎片", ReflectionTools.GetNonPublicField<bool>(data, "_IsPiece")));
        EditorGUILayout.PrefixLabel("道具说明ID");
        ReflectionTools.SetNonPublicField(data, "_Desc", EditorGUILayout.TextArea(ReflectionTools.GetNonPublicField<string>(data, "_Desc")));
    }


    public override void OnInspectorGUI()
    {
        //base.OnInspectorGUI();
        Target.initializedDataMap = false;
        EditorGUILayout.BeginVertical("Box");
        EditorGUILayout.LabelField("ItemDataManager");
        if (GUILayout.Button("添加一个对象")) { Add(); GUI.changed = true; }
        if (GUILayout.Button("清除数据")) { ClearDatas(); GUI.changed = true; }
        EditorGUILayout.Space();
        if (GUILayout.Button("导入数据")) { Load(); GUI.changed = true; }
        if (GUILayout.Button("导出数据")) { ExportDatas(); GUI.changed = true; }
        EditorGUILayout.EndVertical();
        int deleteIndex = -1;

        for (int i = 0, iMax = _dataList.Count; i < iMax; ++i)
        {
            ItemData data = _dataList[i];

            EditorGUILayout.BeginVertical("Box");
            {
                EditorGUI.indentLevel = 1;

                EditorGUILayout.BeginHorizontal();
                {
                    // 标题区
                    UpdateFoldout(i, EditorGUILayout.Foldout(_isFoldList.Contains(i), ReflectionTools.GetNonPublicField<int>(data, "_ItemID").ToString()));
                    // 删除按钮
                    if (GUILayout.Button("X", GUILayout.Width(20))) { deleteIndex = i; }
                }
                EditorGUILayout.EndHorizontal();

                if (_isFoldList.Contains(i))
                {
                    EditorGUILayout.BeginVertical("Box");
                    {
                        OnDataUI(data);
                    }
                    EditorGUILayout.EndVertical();
                }
            }
            EditorGUILayout.EndVertical();
        }

        if (GUI.changed)
        {
            // 去除己删除的对象
            if (deleteIndex >= 0 && deleteIndex < _dataList.Count)
            {
                _isFoldList.Remove(deleteIndex);
                _dataList.RemoveAt(deleteIndex);
            }

            // 保存信息
            EditorUtility.SetDirty(Target);
            GUI.changed = false;
        }
    }


    /// <summary> 添加一个对象 </summary>
    void Add()
    {
        AddDataWindow window = EditorWindow.GetWindow(typeof(AddDataWindow)) as AddDataWindow;
        ItemData data = new ItemData();

        window.SetGUI<ItemData>(() =>
        {
            bool isError = !data.ItemID.IsValid() || Target.Contains(data.ItemID);
            OnDataUI(data);

            GUIStyle style = new GUIStyle(GUI.skin.button);
            style.normal.textColor = isError ? Color.red : Color.white;

            if (GUILayout.Button(isError ? "ID无效或重复" : "添加数据", style) && !isError)
            {
                window.Close();
                _dataList.Add(data);
            }
        });
    }


    /// <summary> 清除数据 </summary>
    void ClearDatas()
    {
        if (EditorUtility.DisplayDialog("清除数据（清除后数据无法找回）", "确定要清除所有数据？", "确定", "取消"))
        {
            _dataList.Clear();
            _isFoldList.Clear();
        }
    }


    /// <summary> 确定是否导入Excel </summary>
    void Load()
    {
        if (EditorUtility.DisplayDialog("导入数据（导入后己编辑的数据无法找回）", "确定要导入该路径表内数据？\n" + ExcelTools.ExcelFilesPath + "/Icon.xlsx", "确定", "取消"))
        {
            LoadExcel();
        }
    }


    /// <summary> 直接导入Excel </summary>
    void LoadExcel()
    {
        DataTable sheet = ExcelTools.GetSheet(ExcelTools.ExcelFilesPath + "/Item.xlsx");
        if (null == sheet) { return; }
        _dataList.Clear();
        ExcelReader eReader = new ExcelReader(sheet);

        for (int i = 4, iMax = eReader.GetRowCount(); i < iMax; ++i)
        {
            string id = eReader.GetData(i, "ItemID");

            // 表中间有ID无效就直接跳出训话
            if (!id.IsValid())
            {
                Debug.LogError("表ID有无效值， 请检查表：Icon");
                EditorUtility.DisplayDialog("导入表格错误", "表ID有无效值， 请检查表：Icon", "确定");
                break;
            }

            ItemData lItemData = ItemData.CreateData(
                    eReader.GetData(i, "ItemID").SafeToInt(), // 道具ID
                    eReader.GetData(i, "Name"), // 道具名称ID
                    eReader.GetData(i, "Icon"), // 道具Icon_ID
                    eReader.GetData(i, "Quality").SafeToInt(), // 道具品质
                    (ItemType)(eReader.GetData(i, "Type").SafeToInt()), // 道具类型
                    eReader.GetData(i, "SType").SafeToInt(), // 是否可以出售
                    eReader.GetData(i, "SPrice").SafeToInt(), // 售出价格
                    eReader.GetData(i, "UType").SafeToInt(), // 是否可以使用
                    eReader.GetData(i, "DropShow"), // 掉落显示
                    eReader.GetData(i, "AddValue").SafeToInt(), // 增加货币
                    eReader.GetData(i, "DropType").SafeToInt(), // 掉落类型
                    eReader.GetData(i, "DropId").SafeToInt(), // 调用掉落库
                    eReader.GetData(i, "IsPiece").SafeToInt() != 0, // 是否碎片
                    eReader.GetData(i, "Desc") // 道具说明ID
                );

            _dataList.Add(lItemData);
        }
    }


    /// <summary> 导出 </summary>
    void ExportDatas()
    {
        string path = Application.dataPath + "/.ExportTabExcle";
        if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); }
        System.IO.StreamWriter sw = new System.IO.StreamWriter(path + "/Item.txt");
        sw.WriteLine("道具ID\t道具名称ID\t道具Icon_ID\t道具品质\t道具类型\t是否可以出售\t售出价格\t是否可以使用\t掉落显示\t增加货币\t掉落类型\t调用掉落库\t是否碎片\t道具说明ID");
        sw.WriteLine("int\tstring\tstring\tint\tItemType\tint\tint\tint\tstring\tint\tint\tint\tbool\tstring");
        sw.WriteLine("C\tC\tC\tC\tC\tC\tC\tC\tC\tC\tC\tC\tC\tC");
        sw.WriteLine("ItemID\tName\tIcon\tQuality\tType\tSType\tSPrice\tUType\tDropShow\tAddValue\tDropType\tDropId\tIsPiece\tDesc");

        for (int i = 0, iMax = _dataList.Count; i < iMax; ++i)
        {
            var data = _dataList[i];

            if (EditorUtility.DisplayCancelableProgressBar("导出：" + Application.dataPath + "/Item.txt", "ID = " + data.ItemID, (float)(i + 1) / iMax))
            {
                break;
            }

            sw.WriteLine((data.ItemID).ToString()+ "\t" +(data.Name).ToString()+ "\t" +(data.Icon).ToString()+ "\t" +(data.Quality).ToString()+ "\t" +((int)data.Type).ToString()+ "\t" +(data.SType).ToString()+ "\t" +(data.SPrice).ToString()+ "\t" +(data.UType).ToString()+ "\t" +(data.DropShow).ToString()+ "\t" +(data.AddValue).ToString()+ "\t" +(data.DropType).ToString()+ "\t" +(data.DropId).ToString()+ "\t" +(data.IsPiece ? 1 : 0).ToString()+ "\t" +(data.Desc).ToString());

        }

        // 关闭文本
        sw.Close();
        // 清除进度条
        EditorUtility.ClearProgressBar();
        // 刷新资源面板显示
        AssetDatabase.Refresh();
    }
}
